/** @file    CoderXML_Communication.cpp
 *  @author  Alessandro Polo
 *  @version $Id: CoderXML_Communication.cpp 1968 2010-02-27 05:52:38Z alex $
 *  @brief
 * File containing methods for Serialization.
 ****************************************************************************/
/* Copyright (c) 2007-2010, WOSH - Wide Open Smart Home 
 * by Alessandro Polo - OpenSmartHome.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or materials provided with the distribution.
 *     * Neither the name of the OpenSmartHome.com WOSH nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY Alessandro Polo ''AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL Alessandro Polo BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ****************************************************************************/

 #include <framework/database/CoderXML_Communication.h>
 #include <framework/database/CoderXML_Core.h>
 #include <framework/database/EncoderXML.h>


using namespace std;
using namespace wosh::communication;
namespace wosh {
 namespace database {

void EncoderXML_register_Communication()
 {
	EncoderXML::registerDataType( _NotificationConversion_TYPE,	new EncoderXML_template__NotificationConversion() );
	EncoderXML::registerDataType( _AudioMessage_TYPE,			new EncoderXML_template__AudioMessage() );
	EncoderXML::registerDataType( _TextMessage_TYPE,			new EncoderXML_template__TextMessage() );
	EncoderXML::registerDataType( _VoiceCall_TYPE,				new EncoderXML_template__VoiceCall() );
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WRESULT EncoderXML_template__AudioMessage::serializeTo( const ISerializable* object_s, QDomDocument& doc, QDomElement& contNode, bool compact )
 {
	if ( object_s == NULL ) return WRET_ERR_PARAM;
	const wosh::communication::AudioMessage* object = dynamic_cast<const wosh::communication::AudioMessage*>(object_s);
	if ( object == NULL ) return WRET_ERR_PARAM;

	EncoderXML_template__Notification().serializeTo( object, doc, contNode, compact );

	contNode.setAttribute("audiotype", QString::number((int)object->getAudioType()) );

	if ( !object->getFile().empty() ) {
		QDomElement uriNode = doc.createElement("fileuri");
		uriNode.appendChild( doc.createTextNode( QString(object->getFile().c_str()) ) );
		contNode.appendChild(uriNode);
	 }

	return WRET_OK;
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WRESULT EncoderXML_template__AudioMessage::deserializeFrom( ISerializable* object_s, const QDomElement& contNode )
 {
 	if ( object_s == NULL ) return WRET_ERR_PARAM;
	wosh::communication::AudioMessage* object = dynamic_cast<wosh::communication::AudioMessage*>(object_s);
	if ( object == NULL ) return WRET_ERR_PARAM;

	EncoderXML_template__Notification().deserializeFrom( object, contNode );

	QDomElement typeNode = contNode.namedItem("audiotype").toElement();
	if ( typeNode.isNull()  )
		object->setAudioType( (AudioMessage::AUDIO_TYPE)contNode.attribute("audiotype").toInt() );
	else
		object->setAudioType( (AudioMessage::AUDIO_TYPE)typeNode.text().toInt() );

	QDomElement uriNode = contNode.namedItem("fileuri").toElement();
	if ( uriNode.isNull()  )
		object->setFile( string( contNode.attribute("fileuri").toLatin1().data() ) );
	else
		object->setFile( string( uriNode.text().toLatin1().data() ) );

	return WRET_OK;
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WRESULT EncoderXML_template__NotificationConversion::serializeTo( const ISerializable* object_s, QDomDocument& doc, QDomElement& contNode, bool compact )
 {
	if ( object_s == NULL ) return WRET_ERR_PARAM;
	const wosh::communication::NotificationConversion* object = dynamic_cast<const wosh::communication::NotificationConversion*>(object_s);
	if ( object == NULL ) return WRET_ERR_PARAM;
	WRESULT ret = WRET_OK;

	if ( object->hasOriginal() ) {
		QDomElement originalNode = doc.createElement("original");
		originalNode.setAttribute("classname", object->getOriginal()->getClassName() );
		ret = EncoderXML::serializeTo(object->getOriginal(), doc, originalNode, compact);
		contNode.appendChild(originalNode);
	}

	contNode.setAttribute("type", QString::number((int)object->getNotificationType()) );
	contNode.setAttribute("protocol", QString::number((int)object->getProtocol()) );

	QDomElement langNode = doc.createElement("language");
	langNode.appendChild( doc.createTextNode( QString(object->getLanguage().c_str()) ) );
	contNode.appendChild(langNode);

	return ret;
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WRESULT EncoderXML_template__NotificationConversion::deserializeFrom( ISerializable* object_s, const QDomElement& contNode )
 {
 	if ( object_s == NULL ) return WRET_ERR_PARAM;
	wosh::communication::NotificationConversion* object = dynamic_cast<wosh::communication::NotificationConversion*>(object_s);
	if ( object == NULL ) return WRET_ERR_PARAM;

	QDomElement originalNode = contNode.namedItem("original").toElement();
	if ( !originalNode.isNull()  ) {
		string content_type( originalNode.attribute("classname").toLatin1().data() );
		EncoderXML_base* obj_ser = EncoderXML::findEncoderFor(content_type);
		if ( obj_ser != NULL ) {
			ISerializable* content_data = obj_ser->allocObject();
			obj_ser->deserializeFrom(content_data, originalNode);
			Notification* notif = dynamic_cast<Notification*>(content_data);
			object->setOriginal(notif);
		 }
	 }


	QDomElement typeNode = contNode.namedItem("type").toElement();
	if ( typeNode.isNull()  )
		object->setNotificationType( (Notification::TYPE)contNode.attribute("type").toInt() );
	else
		object->setNotificationType( (Notification::TYPE)typeNode.text().toInt() );

	QDomElement protoNode = contNode.namedItem("protocol").toElement();
	if ( protoNode.isNull()  )
		object->setProtocol( (Notification::PROTOCOL)contNode.attribute("protocol").toInt() );
	else
		object->setProtocol( (Notification::PROTOCOL)protoNode.text().toInt() );

	QDomElement langNode = contNode.namedItem("language").toElement();
	if ( langNode.isNull()  )
		object->setLanguage( string( contNode.attribute("language").toLatin1().data() ) );
	else
		object->setLanguage( string( langNode.text().toLatin1().data() ) );

	return WRET_OK;
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WRESULT EncoderXML_template__TextMessage::serializeTo( const ISerializable* object_s, QDomDocument& doc, QDomElement& contNode, bool compact )
 {
	if ( object_s == NULL ) return WRET_ERR_PARAM;
	const wosh::communication::TextMessage* object = dynamic_cast<const wosh::communication::TextMessage*>(object_s);
	if ( object == NULL ) return WRET_ERR_PARAM;

	EncoderXML_template__Notification().serializeTo( object, doc, contNode, compact );

	if ( object->getSubject() != "" ) {
		QDomElement briefNode = doc.createElement("subject");
		briefNode.appendChild( doc.createTextNode( QString(object->getSubject().c_str()) ) );
		contNode.appendChild(briefNode);
	 }
	if ( object->getPlain() != "" ) {
		QDomElement plainNode = doc.createElement("plain");
		plainNode.appendChild( doc.createTextNode( QString(object->getPlain().c_str()) ) );
		contNode.appendChild(plainNode);
	 }


	return WRET_OK;
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WRESULT EncoderXML_template__TextMessage::deserializeFrom( ISerializable* object_s, const QDomElement& contNode )
 {
 	if ( object_s == NULL ) return WRET_ERR_PARAM;
	wosh::communication::TextMessage* object = dynamic_cast<wosh::communication::TextMessage*>(object_s);
	if ( object == NULL ) return WRET_ERR_PARAM;

	EncoderXML_template__Notification().deserializeFrom( object, contNode );

	QDomElement briefNode = contNode.namedItem("subject").toElement();
	if ( briefNode.isNull()  )
		object->setSubject( string( contNode.attribute("subject").toLatin1().data() ) );
	else
		object->setSubject( string( briefNode.text().toLatin1().data() ) );

	QDomElement plainNode = contNode.namedItem("plain").toElement();
	if ( plainNode.isNull()  )
		object->setPlain( string( contNode.attribute("plain").toLatin1().data() ) );
	else
		object->setPlain( string( plainNode.text().toLatin1().data() ) );

	return WRET_OK;
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WRESULT EncoderXML_template__VoiceCall::serializeTo( const ISerializable* object_s, QDomDocument& doc, QDomElement& contNode, bool compact )
 {
	if ( object_s == NULL ) return WRET_ERR_PARAM;
	const wosh::communication::VoiceCall* object = dynamic_cast<const wosh::communication::VoiceCall*>(object_s);
	if ( object == NULL ) return WRET_ERR_PARAM;

	EncoderXML_template__Notification().serializeTo( object, doc, contNode, compact );

	if ( compact ) {
		contNode.setAttribute("duration", QString::number(object->getDuration()) );
	}
	else {
		QDomElement dur_node = doc.createElement("duration");
		dur_node.appendChild( doc.createTextNode( QString::number(object->getDuration()) ) );
		contNode.appendChild(dur_node);
	}

	QString cStat( wosh::communication::VoiceCall::getCallStatusAsString(object->getCallStatus()).c_str() );
	QDomElement status_node = doc.createElement("call-status");
	status_node.appendChild( doc.createTextNode(cStat) );
	contNode.appendChild(status_node);

	QString cType( wosh::communication::VoiceCall::getCallTypeAsString(object->getCallType()).c_str() );
	QDomElement type_node = doc.createElement("call-type");
	type_node.appendChild( doc.createTextNode(cType) );
	contNode.appendChild(type_node);

	return WRET_OK;
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WRESULT EncoderXML_template__VoiceCall::deserializeFrom( ISerializable* object_s, const QDomElement& contNode )
 {
 	if ( object_s == NULL ) return WRET_ERR_PARAM;
	wosh::communication::VoiceCall* object = dynamic_cast<wosh::communication::VoiceCall*>(object_s);
	if ( object == NULL ) return WRET_ERR_PARAM;

	EncoderXML_template__Notification().deserializeFrom( object, contNode );

	QDomElement dur_node = contNode.namedItem("duration").toElement();
	if ( dur_node.isNull() )
		object->setDuration( contNode.attribute("duration").toLong() );
	else
		object->setDuration( dur_node.text().toLong() );


	QString cStat;
	QDomElement status_node = contNode.namedItem("call-status").toElement();
	if ( status_node.isNull() )
		cStat = contNode.attribute("call-status");
	else
		cStat = status_node.text();
	object->setCallStatus(wosh::communication::VoiceCall::getCallStatusFromString(cStat.toLatin1().data()));

	QString cType;
	QDomElement type_node = contNode.namedItem("call-type").toElement();
	if ( type_node.isNull() )
		cType = contNode.attribute("call-type");
	else
		cType = type_node.text();
	object->setCallType(wosh::communication::VoiceCall::getCallTypeFromString(cType.toLatin1().data()));

	return WRET_OK;
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

 }; // namespace database
}; // namespace wosh
